import 'package:flutter/material.dart';

import '../../base/chart_entity.dart';

/// 饼状图基础数据
class BasePieChartEntity extends ChartEntity {
  BasePieChartEntity(
      {required this.color,
      this.drawLabel = false,
      this.label,
      this.labelSize = 10,
      this.labelColor = Colors.black,
      this.addedRadius = 0,
      super.value,
      super.isDraw,
      super.data});

  /// 扇形的颜色
  final Color color;

  /// 是否绘制标签
  final bool drawLabel;

  /// 标签
  final String? label;

  /// 标签字体大小
  final double labelSize;

  /// 标签字体颜色
  final Color labelColor;

  /// 在[KqBasePieChart.radius]补充半径
  final double addedRadius;

  /// 绘制的起始角度
  double get drawStartAngle => _drawStartAngle;
  double _drawStartAngle = 0;

  /// 非自定义绘制不要主动赋值
  set $drawStartAngle(double angle) => _drawStartAngle = angle;

  /// 绘制的结束角度
  double get drawSweepAngle => _drawSweepAngle;
  double _drawSweepAngle = 0;

  /// 非自定义绘制不要主动赋值
  set $drawSweepAngle(double angle) => _drawSweepAngle = angle;

  /// 绘制的半径
  double get drawRadius => _drawRadius;
  double _drawRadius = 0;

  /// 非自定义绘制不要主动赋值
  set $drawRadius(double radius) => _drawRadius = radius;

  /// x轴/Y轴相较于圆心坐标偏移距离
  Offset get offset => _offset;
  Offset _offset = Offset.zero;

  /// 非自定义绘制不要主动赋值
  set $offset(Offset offset) => _offset = offset;
}

/// 饼状图标签绘制位置
class LabelPosition {
  const LabelPosition._internal();

  /// 绘制在扇形内部
  ///
  /// [offsetCenterPercent]表示离圆心的偏移百分比，相对于圆的半径
  static InSide inside({double offsetCenterPercent = 0.6}) =>
      InSide._newInstance(offsetCenterPercent);

  /// 默认的标签指示线构建器
  static IndicatorLine _defaultLineFactory(entity) {
    return const IndicatorLine();
  }

  /// 绘制在扇形内部
  ///
  /// [offsetCenterPercent]表示离圆心的偏移百分比，相对于圆的半径
  static OutSide outside(
          {LabelGravity labelGravity = LabelGravity.top,
          LineFactory lineFactory = _defaultLineFactory}) =>
      OutSide._newInstance(labelGravity, lineFactory);
}

/// 饼状图标签绘制在扇形内部
class InSide extends LabelPosition {
  const InSide._newInstance(this.offsetCenterPercent) : super._internal();

  /// 离圆心的偏移百分比，相对于圆的半径
  final double offsetCenterPercent;
}

/// 饼状图标签绘制在扇形外部
class OutSide extends LabelPosition {
  const OutSide._newInstance(this.labelGravity, this.lineFactory) : super._internal();

  /// 标签在垂直方向的绘制位置
  final LabelGravity labelGravity;

  /// 标签指示线构建工厂
  final LineFactory lineFactory;
}

/// 创建饼状图标签线条指示器
typedef LineFactory = IndicatorLine Function(BasePieChartEntity entity);

/// 标签在垂直方向的绘制位置
enum LabelGravity {
  /// 绘制到线条尾部，垂直方向上字体中间和线条持平
  end,

  /// 绘制到线条上面
  top,

  /// 绘制到线条下面
  bottom
}

/// 标签指示线
class IndicatorLine {
  const IndicatorLine(
      {this.color = Colors.black,
      this.width = 2,
      this.maxLength,
      this.minLength = 0,
      this.offset = 0,
      this.drawStartCircle = false,
      this.circleRadius = 2,
      this.circleColor = Colors.grey})
      : assert(minLength >= 0, "minLength must than or equal zero"),
        assert(width > 0, "width must than zero"),
        assert(!drawStartCircle || circleRadius > 0,
            "set drawStartCircle, circleRadius must than zero");

  /// 线条颜色
  final Color color;

  /// 线条粗细
  final double width;

  /// 线条最大长度，不设置则取文本的宽度。设置则文本最大绘制宽度为当前设定值
  final double? maxLength;

  /// 线条最小长度
  final double minLength;

  /// 线条与饼状图偏移值,相对于饼状图边界
  final double offset;

  /// 是否在线条起始处位置一个圆点
  final bool drawStartCircle;

  /// 圆点半径
  final double circleRadius;

  /// 圆点颜色
  final Color circleColor;
}
